﻿@page "/GridEditFormTemplateValidation"
@layout DataProviderAccessArea<INwindDataProvider>

<DemoPageSectionComponent Id="DataGrid-Validation" ShowHorizontalScrollBar="true">
    @inject NwindDataService NwindDataService

    @if(Data == null) {
        <p><em>Loading...</em></p>
    } else {
        <DxDataGrid @ref="@grid"
                    Data="@Data"
                    PageSize="12"
                    RowRemovingAsync="@OnRowRemovingAsync"
                    RowEditStart="@(dataItem => OnRowEditStarting(dataItem))"
                    RowInsertStart="@(() => OnRowEditStarting(null))">
            <Columns>
                <DxDataGridCommandColumn Width="150px" />
                <DxDataGridColumn Field="@nameof(Employee.FirstName)" />
                <DxDataGridColumn Field="@nameof(Employee.LastName)" />
                <DxDataGridColumn Field="@nameof(Employee.Title)" />
                <DxDataGridColumn Field="@nameof(Employee.TitleOfCourtesy)" Width="150px" />
                <DxDataGridDateEditColumn Field="@nameof(Employee.BirthDate)" Width="150px" />
                <DxDataGridDateEditColumn Field="@nameof(Employee.HireDate)" Width="150px" />
            </Columns>
            <EditFormTemplate>
                <EditForm Model="@EditContext" Context="EditFormContext" OnValidSubmit="@HandleValidSubmit">
                    <DataAnnotationsValidator />
                    <DxFormLayout>
                        <DxFormLayoutItem Caption="First Name:" ColSpanMd="6" Context="FormLayoutContext">
                            <DxTextBox @bind-Text="@EditContext.FirstName" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem Caption="Last Name:" ColSpanMd="6" Context="FormLayoutContext">
                            <DxTextBox @bind-Text="@EditContext.LastName" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem Caption="Title:" ColSpanMd="6" Context="FormLayoutContext">
                            <DxTextBox @bind-Text="@EditContext.Title" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem Caption="Title of Courtesy:" ColSpanMd="6" Context="FormLayoutContext">
                            <DxTextBox @bind-Text="@EditContext.TitleOfCourtesy" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem Caption="Birth Date:" ColSpanMd="6" Context="FormLayoutContext">
                            <DxDateEdit @bind-Date="@EditContext.BirthDate" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem Caption="Hire Date:" ColSpanMd="6" Context="FormLayoutContext">
                            <DxDateEdit @bind-Date="@EditContext.HireDate" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem Caption="Notes:" ColSpanMd="12" Context="FormLayoutContext">
                            <DxMemo @bind-Text="@EditContext.Notes" Rows="5" />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem ColSpanMd="12" Context="FormLayoutContext">
                            <ValidationSummary />
                        </DxFormLayoutItem>
                        <DxFormLayoutItem ColSpanMd="12" Context="FormLayoutContext">
                            <div class="text-end">
                                <DxButton RenderStyle="ButtonRenderStyle.Primary" SubmitFormOnClick="true" Text="Update" />
                                <DxButton RenderStyle="ButtonRenderStyle.Link" Click="OnCancelButtonClick" Text="Cancel" />
                            </div>
                        </DxFormLayoutItem>
                    </DxFormLayout>
                </EditForm>
            </EditFormTemplate>
        </DxDataGrid>
    }

    @code {
        DxDataGrid<EditableEmployee> grid;
        IEnumerable<EditableEmployee> Data { get; set; }

        protected override async Task OnInitializedAsync() {
            Data = await NwindDataService.GetEmployeesEditableAsync();
        }
        protected override async Task OnAfterRenderAsync(bool firstRender) {
            if(firstRender) {
                await grid.StartRowEdit(null);
            }
        }

        class FormEditContext {
            public FormEditContext(EditableEmployee dataItem) {
                DataItem = dataItem;
                if(DataItem == null) {
                    DataItem = new EditableEmployee();
                    IsNewRow = true;
                }
                FirstName = DataItem.FirstName;
                LastName = DataItem.LastName;
                Title = DataItem.Title;
                TitleOfCourtesy = DataItem.TitleOfCourtesy;
                BirthDate = DataItem.BirthDate;
                HireDate = DataItem.HireDate;
                Notes = DataItem.Notes;
            }

            public EditableEmployee DataItem { get; set; }
            public bool IsNewRow { get; set; }

            [Required]
            public string FirstName { get; set; }
            [Required]
            public string LastName { get; set; }
            [Required]
            public string Title { get; set; }
            public string TitleOfCourtesy { get; set; }
            [Required]
            [Range(typeof(DateTime), "1/1/1970", "1/1/2020",
            ErrorMessage = "BirthDate must be between {1:d} and {2:d}")]
            public DateTime? BirthDate { get; set; }
            [Required]
            [Range(typeof(DateTime), "1/1/2000", "1/1/2020",
            ErrorMessage = "HireDate must be between {1:d} and {2:d}")]
            public DateTime? HireDate { get; set; }
            [Required]
            [StringLength(maximumLength: 256, MinimumLength = 4,
            ErrorMessage = "The Notes should be 4 to 256 characters.")]
            public string Notes { get; set; }

            public Action StateHasChanged { get; set; }
        }

        FormEditContext EditContext = null;
        void OnRowEditStarting(EditableEmployee employee) {
            EditContext = new FormEditContext(employee);
            EditContext.StateHasChanged += () => { InvokeAsync(StateHasChanged); };
        }
        async Task OnCancelButtonClick() {
            await grid.CancelRowEdit();
            EditContext = null;
        }
        async Task HandleValidSubmit() {
            EditContext.DataItem.FirstName = EditContext.FirstName;
            EditContext.DataItem.LastName = EditContext.LastName;
            EditContext.DataItem.Title = EditContext.Title;
            EditContext.DataItem.TitleOfCourtesy = EditContext.TitleOfCourtesy;
            EditContext.DataItem.BirthDate = EditContext.BirthDate;
            EditContext.DataItem.HireDate = EditContext.HireDate;
            EditContext.DataItem.Notes = EditContext.Notes;

            if(EditContext.IsNewRow) {
                await NwindDataService.InsertEmployeeAsync(EditContext.DataItem);
            } else {
                await NwindDataService.UpdateEmployeeAsync(EditContext.DataItem, new Dictionary<string, object>());
            }

            await grid.CancelRowEdit();
            Data = await NwindDataService.GetEmployeesEditableAsync();
            StateHasChanged();
        }
        async Task OnRowRemovingAsync(EditableEmployee dataItem) {
            await NwindDataService.RemoveEmployeeAsync(dataItem);
            Data = await NwindDataService.GetEmployeesEditableAsync();
            StateHasChanged();
        }
    }
</DemoPageSectionComponent>
